package com.baizhi.shiro;

import com.baizhi.dao.CmfzAdminDao;
import com.baizhi.entity.CmfzAdmin;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

/*自定义realm类
    该类的目的是：将shiro框架默认从配置文件shiro.ini中读取验证数据 修改为从数据库中获取数据进行验证
    自定义realm类主要分以下几个步骤：
    1、继承一个类AuthenticatingRealm认证类
    2、重写其中的doGetAuthenticationInfo（token）方法  获取认证信息
* */
public class DemoRealm extends AuthenticatingRealm {
    //装配一个管理员dao接口对象  用于查询数据库
    @Autowired
    private CmfzAdminDao cmfzAdminDao;
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//        1、获取token中的账户名   首先需要将形参中的token强转为UsernamePasswordToken
        UsernamePasswordToken token2 = (UsernamePasswordToken) token;
        String username = token2.getUsername();//token中有获取其中账号和密码的方法
//        2、根据上面的用户名 去数据库中查询对应的管理员对象
        CmfzAdmin cmfzAdmin = cmfzAdminDao.selectOne(new QueryWrapper<CmfzAdmin>().eq("username", username));
//        3、根据数据库查询的结果 进行判断  返回结果
        if(cmfzAdmin!=null){
            //说明数据库有对应数据  认证成功  此时需要设置返回的info对象(账户对象)
            /*SimpleAccount需要三个参数：
                参数1：数据库查询出的账户名
                参数2：数据库查询出的密码
                参数3：当前对象的名字
            * */
            SimpleAccount simpleAccount =
                    new SimpleAccount(cmfzAdmin.getUsername(), cmfzAdmin.getPassword(), this.getName());
            /*
            * 注意：若是使用了shiro进行加密处理  此处需要再提供一个参数
            * 参数1和2和上面一样 不变
            * 参数3：改为从数据库查询出的盐值数据  并且要把此值处理为ByteSource类型的数据才能做参数
            * 参数4：当前对象名字
            * */
            String salt = cmfzAdmin.getSalt();//获取数据库中的盐值
            ByteSource bytes = ByteSource.Util.bytes(salt);//将盐值处理为ByteSource类型的（注意是shiro包下的类）
            SimpleAccount simpleAccount2 =
                    new SimpleAccount(cmfzAdmin.getUsername(), cmfzAdmin.getPassword(), bytes, cmfzAdmin.getUsername());
            return simpleAccount2;
        }
        //否则 说明认证失败  没查询到对应的数据  直接返回null即可
        return null;
    }
}
